#include <boost/atomic.hpp>

#include <disruptor/claim_strategy.h>
//  Copyright (c) 2011 Helge Bahmann
//
//  Distributed under the Boost Software License, Version 1.0.
//  See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)

namespace boost {

ClaimStrategyInterface* CreateClaimStrategy(ClaimStrategyOption option,
	const int& buffer_size) {
		switch (option) {
	case kSingleThreadedStrategy:
		return new SingleThreadedStrategy(buffer_size);
		// case kMultiThreadedStrategy:
		//     return new MultiThreadedStrategy(buffer_size);
	default:
		return NULL;
		}
}

WaitStrategyInterface* CreateWaitStrategy(WaitStrategyOption wait_option) {
	switch (wait_option) {
		case kBlockingStrategy:
			return new BlockingStrategy();
		case kSleepingStrategy:
			return new SleepingStrategy();
		case kYieldingStrategy:
			return new YieldingStrategy();
		case kBusySpinStrategy:
			return new BusySpinStrategy();
		default:
			return NULL;
	}
}


int64_t GetMinimumSequence(const std::vector<Sequence*>& sequences) {
	  int64_t minimum = LONG_MAX;

	  for (std::vector<Sequence*>::const_iterator sequence_ = sequences.begin();
		  sequence_ != sequences.end(); ++sequence_) {
			  int64_t sequence = (*sequence_)->sequence();
			  minimum = minimum < sequence ? minimum : sequence;
	  }

	  return minimum;
}


namespace atomics {
namespace detail {

static lockpool::lock_type lock_pool_[41];

// NOTE: This function must NOT be inline. Otherwise MSVC 9 will sometimes generate broken code for modulus operation which result in crashes.
BOOST_ATOMIC_DECL lockpool::lock_type& lockpool::get_lock_for(const volatile void* addr)
{
    std::size_t index = reinterpret_cast<std::size_t>(addr) % (sizeof(lock_pool_) / sizeof(*lock_pool_));
    return lock_pool_[index];
}

}
}
}
